package cn.schoolwow.workflow.module.instance.query.flow;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.database.dql.condition.Condition;
import cn.schoolwow.quickdao.domain.database.dql.subCondition.SubCondition;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.workflow.domain.instance.WorkFlowInstanceQuery;
import cn.schoolwow.workflow.entity.WorkFlowDefinition;
import cn.schoolwow.workflow.entity.WorkFlowInstance;
import cn.schoolwow.workflow.entity.WorkFlowInstanceCarbonCopy;
import cn.schoolwow.workflow.entity.WorkFlowTask;
import cn.schoolwow.workflow.module.common.flow.AddContextDataQueryFlow;

import java.util.List;

public class GetWorkFlowInstanceConditionFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setWorkFlowInstanceId(flowContext);
        setCondition(flowContext);
        setWorkFlowDefinitionSubCondition(flowContext);
        setCarbonCopySubCondition(flowContext);
    }

    @Override
    public String name() {
        return "获取查询工作流实例对象";
    }

    private void setWorkFlowInstanceId(FlowContext flowContext){
        DAO dao = flowContext.checkInstanceData(DAO.class);
        WorkFlowInstanceQuery workFlowInstanceQuery = flowContext.checkInstanceData(WorkFlowInstanceQuery.class);

        if(workFlowInstanceQuery.taskIdList.isEmpty()
                &&workFlowInstanceQuery.assignerList.isEmpty()
                &&workFlowInstanceQuery.taskTypeList.isEmpty()
        ){
            return;
        }
        Condition condition = dao.query(WorkFlowTask.class)
                .distinct()
                .addColumn("instanceId");
        if(!workFlowInstanceQuery.taskIdList.isEmpty()){
            condition.addInQuery("id", workFlowInstanceQuery.taskIdList);
        }
        if(!workFlowInstanceQuery.assignerList.isEmpty()){
            condition.addInQuery("assigner", workFlowInstanceQuery.assignerList);
        }
        if(!workFlowInstanceQuery.taskTypeList.isEmpty()){
            condition.addInQuery("type", workFlowInstanceQuery.taskTypeList);
        }
        dao.addRecordString("获取查询工作流实例对象-根据工作流任务相关条件查询实例id列表");
        List<Long> instanceIdList = condition.execute().getSingleColumnList(Long.class);
        //如果为空,则说明没有实例列表
        if(instanceIdList.isEmpty()){
            Condition condition1 = dao.query(WorkFlowInstance.class)
                    .addRawQuery("1 = 2");
            flowContext.putInstanceData(condition1, Condition.class);
            flowContext.brokenCurrentFlow("查询结果为空");
        }
        workFlowInstanceQuery.instanceIdList.addAll(instanceIdList);
    }

    private void setCondition(FlowContext flowContext){
        WorkFlowInstanceQuery workFlowInstanceQuery = flowContext.checkInstanceData(WorkFlowInstanceQuery.class);
        DAO dao = flowContext.checkInstanceData(DAO.class);

        Condition condition = dao.query(WorkFlowInstance.class)
                .addTableColumn()
                .orderByDesc("createdAt");
        if(null!=workFlowInstanceQuery.definitionIdList){
            condition.addInQuery("definitionId", workFlowInstanceQuery.definitionIdList);
        }
        if(!workFlowInstanceQuery.instanceIdList.isEmpty()){
            condition.addInQuery("id", workFlowInstanceQuery.instanceIdList);
        }
        if(!workFlowInstanceQuery.instanceNameList.isEmpty()){
            condition.addInQuery("name", workFlowInstanceQuery.instanceNameList);
        }
        if(!workFlowInstanceQuery.initiatorList.isEmpty()){
            condition.addInQuery("initiator", workFlowInstanceQuery.initiatorList);
        }
        if(!workFlowInstanceQuery.statusList.isEmpty()){
            condition.addInQuery("status", workFlowInstanceQuery.statusList);
        }
        flowContext.startFlow(new AddContextDataQueryFlow())
                .putInstanceData(condition, Condition.class)
                .putTemporaryData("contextDataQueryList", workFlowInstanceQuery.contextDataQueryList)
                .execute();

        if(null!=workFlowInstanceQuery.submitTimeDuration){
            if(null!=workFlowInstanceQuery.submitTimeDuration.startTime){
                condition.addQuery("createdAt", ">=", workFlowInstanceQuery.submitTimeDuration.startTime);
            }
            if(null!=workFlowInstanceQuery.submitTimeDuration.endTime){
                condition.addQuery("createdAt", "<=", workFlowInstanceQuery.submitTimeDuration.endTime);
            }
        }
        if(null!=workFlowInstanceQuery.finishTimeDuration){
            if(null!=workFlowInstanceQuery.finishTimeDuration.startTime){
                condition.addQuery("updatedAt", ">=", workFlowInstanceQuery.finishTimeDuration.startTime);
            }
            if(null!=workFlowInstanceQuery.finishTimeDuration.endTime){
                condition.addQuery("updatedAt", "<=", workFlowInstanceQuery.finishTimeDuration.endTime);
            }
        }
        flowContext.putTemporaryInstanceData(condition, Condition.class);
    }

    private void setWorkFlowDefinitionSubCondition(FlowContext flowContext){
        Condition condition = flowContext.checkInstanceData(Condition.class);
        WorkFlowInstanceQuery workFlowInstanceQuery = flowContext.checkInstanceData(WorkFlowInstanceQuery.class);

        SubCondition workFlowDefinitionSubCondition = condition.joinTable(WorkFlowDefinition.class, "definitionId", "id");
        if(null!=workFlowInstanceQuery.definitionNameList){
            condition.addInQuery("name", workFlowInstanceQuery.definitionNameList);
        }
        flowContext.putCurrentFlowData("workFlowDefinitionSubCondition", workFlowDefinitionSubCondition);
    }

    private void setCarbonCopySubCondition(FlowContext flowContext){
        WorkFlowInstanceQuery workFlowInstanceQuery = flowContext.checkInstanceData(WorkFlowInstanceQuery.class);
        if(workFlowInstanceQuery.carbonCopyList.isEmpty()){
            return;
        }

        DAO dao = flowContext.checkInstanceData(DAO.class);
        Condition condition = flowContext.checkInstanceData(Condition.class);

        dao.addRecordString("根据抄送人列表查询实例id列表");
        SubCondition workFlowInstanceCarbonCopySubCondition = condition.joinTable(WorkFlowInstanceCarbonCopy.class, "id", "instanceId")
                .addInQuery("carbonCopy", workFlowInstanceQuery.carbonCopyList);
        flowContext.putTemporaryData("workFlowInstanceCarbonCopySubCondition", workFlowInstanceCarbonCopySubCondition);
    }

}
